package cn.jingyuan.bee.utils.text.csv;

import cn.jingyuan.bee.utils.io.FileUtils;
import cn.jingyuan.bee.utils.io.IORuntimeException;

import java.io.File;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.file.Path;

/**
 * CSV 文件读取器，参考：FastCSV
 */
public class CsvReader extends CsvBaseReader {

    private final Reader reader;

    /**
     * 构造，使用默认配置项
     */
    public CsvReader() {
        this(null);
    }

    /**
     * 构造
     *
     * @param config 配置项
     */
    public CsvReader(CsvReadConfig config) {
        this((Reader) null, config);
    }

    /**
     * 构造，默认 {@link #DEFAULT_CHARSET} 编码
     *
     * @param file CSV 文件路径，null 表示不设置路径
     * @param config 配置项，null 表示默认配置
     */
    public CsvReader(File file, CsvReadConfig config) {
        this(file, DEFAULT_CHARSET, config);
    }

    /**
     * 构造，默认 {@link #DEFAULT_CHARSET} 编码
     *
     * @param path CSV 文件路径，null 表示不设置路径
     * @param config 配置项，null 表示默认配置
     */
    public CsvReader(Path path, CsvReadConfig config) {
        this(path, DEFAULT_CHARSET, config);
    }

    /**
     * 构造
     *
     * @param file CSV 文件路径，null 表示不设置路径
     * @param charset 编码
     * @param config 配置项，null 表示默认配置
     */
    public CsvReader(File file, Charset charset, CsvReadConfig config) {
        this(FileUtils.getReader(file, charset), config);
    }

    /**
     * 构造
     *
     * @param path CSV 文件路径，null 表示不设置路径
     * @param charset 编码
     * @param config 配置项，null 表示默认配置
     */
    public CsvReader(Path path, Charset charset, CsvReadConfig config) {
        this(FileUtils.getReader(path, charset), config);
    }

    /**
     * 构造
     *
     * @param reader {@link Reader}，null 表示不设置默认 reader
     * @param config 配置项，null 表示默认配置
     */
    public CsvReader(Reader reader, CsvReadConfig config) {
        super(config);
        this.reader = reader;
    }

    /**
     * 读取 CSV 文件，此方法只能调用一次<br>
     * 调用此方法的前提是构造中传入文件路径或 Reader
     *
     * @return {@link CsvData}，包含数据列表和行信息
     *
     * @throws IORuntimeException IO 异常
     */
    public CsvData read() throws IORuntimeException {
        return read(this.reader);
    }

    /**
     * 读取 CSV 数据，此方法只能调用一次<br>
     * 调用此方法的前提是构造中传入文件路径或 Reader
     *
     * @param rowHandler 行处理器，用于一行一行的处理数据
     *
     * @throws IORuntimeException IO 异常
     */
    public void read(CsvRowHandler rowHandler) throws IORuntimeException {
        read(this.reader, rowHandler);
    }

}
